import 'dart:async';

import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
import 'package:get/get.dart';
import 'package:openim/routes/app_navigator.dart';
import 'package:openim_common/openim_common.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;

class ChatHistorySearchLogic extends GetxController {
  final TextEditingController searchController = TextEditingController();
  final FocusNode searchFocusNode = FocusNode();
  
  late String conversationID;
  late ConversationInfo conversationInfo;
  
  // 搜索结果
  final RxList<Message> searchResults = <Message>[].obs;
  final RxBool isSearching = false.obs;
  final RxBool hasSearched = false.obs;
  final RxString searchKeyword = ''.obs;
  final RxBool hasSearchText = false.obs; // 新增：跟踪输入框是否有内容
  
  // 分页相关
  int currentPage = 1;
  final int pageSize = 20;
  bool hasMoreData = true;
  
  // 搜索类型筛选
  final RxInt selectedSearchType = 0.obs; // 0: 全部, 1: 文本, 2: 图片, 3: 文件
  final List<String> searchTypes = ['全部', '文本', '图片', '文件'];

  @override
  void onInit() {
    conversationID = Get.arguments['conversationID'] ?? '';
    conversationInfo = Get.arguments['conversationInfo'];
    
    // 监听搜索输入
    searchController.addListener(_onSearchChanged);
    
    super.onInit();
  }

  @override
  void onClose() {
    searchController.dispose();
    searchFocusNode.dispose();
    super.onClose();
  }

  void _onSearchChanged() {
   final keyword = searchController.text.trim();
    hasSearchText.value = keyword.isNotEmpty; // 更新响应式变量
    if (keyword.isEmpty) {
      searchResults.clear();
      hasSearched.value = false;
      searchKeyword.value = '';
    }
  }

  // 执行搜索
  void performSearch() async {
    final keyword = searchController.text.trim();
    if (keyword.isEmpty) return;

    isSearching.value = true;
    hasSearched.value = true;
    searchKeyword.value = keyword;
    currentPage = 1;
    hasMoreData = true;
    searchResults.clear();

    try {
      await _searchMessages(keyword, isNewSearch: true);
    } catch (e) {
      IMViews.showToast('搜索失败：$e');
    } finally {
      isSearching.value = false;
    }
  }

  // 加载更多搜索结果
  void loadMoreResults() async {
    if (!hasMoreData || isSearching.value) return;

    isSearching.value = true;
    try {
      await _searchMessages(searchKeyword.value);
    } catch (e) {
      IMViews.showToast('加载失败：$e');
    } finally {
      isSearching.value = false;
    }
  }

  // 搜索消息
  Future<void> _searchMessages(String keyword, {bool isNewSearch = false}) async {
    if (isNewSearch) {
      currentPage = 1;
    }

    try {
      // 生成模糊搜索关键词列表
      final keywordList = _generateFuzzyKeywords(keyword);
      
      final result = await OpenIM.iMManager.messageManager.searchLocalMessages(
        conversationID: conversationID,
        keywordList: keywordList,
        messageTypeList: _getMessageTypesBySearchType(),
        pageIndex: currentPage,
        count: pageSize,
      );

      if (result.searchResultItems?.isNotEmpty == true) {
        final messages = result.searchResultItems!
            .expand((item) => item.messageList ?? <Message>[])
            .toList();

        // 对搜索结果进行模糊匹配过滤和排序
        final filteredMessages = _filterAndSortMessages(messages, keyword);

        if (isNewSearch) {
          searchResults.assignAll(filteredMessages);
        } else {
          searchResults.addAll(filteredMessages);
        }

        currentPage++;
        hasMoreData = messages.length >= pageSize;
      } else {
        hasMoreData = false;
      }
    } catch (e) {
      print('搜索消息失败: $e');
      hasMoreData = false;
      rethrow;
    }
  }
  // 生成模糊搜索关键词列表
  List<String> _generateFuzzyKeywords(String keyword) {
    final keywords = <String>[];
    
    // 添加原始关键词
    keywords.add(keyword);
    
    // 如果关键词长度大于1，添加部分匹配的关键词
    if (keyword.length > 1) {
      // 添加前缀匹配
      for (int i = 1; i < keyword.length; i++) {
        keywords.add(keyword.substring(0, i + 1));
      }
      
      // 添加后缀匹配
      for (int i = 1; i < keyword.length; i++) {
        keywords.add(keyword.substring(i));
      }
      
      // 如果关键词包含空格，按空格分割
      if (keyword.contains(' ')) {
        keywords.addAll(keyword.split(' ').where((word) => word.isNotEmpty));
      }
      
      // 如果关键词长度大于2，添加中间部分匹配
      if (keyword.length > 2) {
        for (int i = 1; i < keyword.length - 1; i++) {
          for (int j = i + 1; j < keyword.length; j++) {
            keywords.add(keyword.substring(i, j + 1));
          }
        }
      }
    }
    
    // 去重并返回
    return keywords.toSet().toList();
  }
  String _basename(String? p) {
    if (p == null || p.isEmpty) return '';
    final parts = p.split(RegExp(r'[\/\\]'));
    return parts.isNotEmpty ? parts.last : p;
  }

  // 提取图片/视频的“可用于匹配的名称”（本地路径文件名优先，其次URL文件名）
  String _extractMediaName(Message message) {
    if (message.contentType == MessageType.picture) {
      final localPath = message.pictureElem?.sourcePath;
      final url = message.pictureElem?.sourcePicture?.url ??
          message.pictureElem?.snapshotPicture?.url;
      final localName = _basename(localPath);
      return localName.isNotEmpty ? localName : _basename(url);
    } else if (message.contentType == MessageType.video) {
      final localPath = message.videoElem?.videoPath;
      final url = message.videoElem?.videoUrl ?? message.videoElem?.snapshotUrl;
      final localName = _basename(localPath);
      return localName.isNotEmpty ? localName : _basename(url);
    }
    return '';
  }
  // 过滤和排序搜索结果（严格关键字匹配）
  List<Message> _filterAndSortMessages(List<Message> messages, String keyword) {
    final filteredMessages = <Message>[];
    final lowerKeyword = keyword.trim().toLowerCase();

    for (final message in messages) {
      bool match = false;

      if (selectedSearchType.value == 2) {
        // 图片/视频类型：按文件名匹配
        if (message.contentType == MessageType.picture ||
            message.contentType == MessageType.video) {
          if (lowerKeyword.isEmpty) {
            match = true;
          } else {
            final name = _extractMediaName(message).toLowerCase();
            match = name.isNotEmpty && name.contains(lowerKeyword);
          }
        }
      } else if (selectedSearchType.value == 3) {
        // 文件类型：按文件名匹配
        if (message.contentType == MessageType.file) {
          final fileName = message.fileElem?.fileName?.toLowerCase() ?? '';
          match = lowerKeyword.isEmpty
              ? true
              : fileName.isNotEmpty && fileName.contains(lowerKeyword);
        }
      } else {
        // 文本或全部类型：仅对文本类按显示内容匹配（严格 contains）
        final isTextMsg = message.contentType == MessageType.text ||
            message.contentType == MessageType.atText ||
            message.contentType == MessageType.quote ||
            message.contentType == MessageType.advancedText;
        if (isTextMsg) {
          final content = getMessageDisplayContent(message).toLowerCase();
          match = lowerKeyword.isEmpty
              ? true
              : content.isNotEmpty && content.contains(lowerKeyword);
        } else if (lowerKeyword.isEmpty) {
          // 当关键字为空且选择“全部”，保留非文本消息以便完整浏览
          match = true;
        } else {
          match = false;
        }
      }

      if (match) {
        // 关键字为空时按时间排序；有关键字时也按时间排序（严格匹配不需要评分）
        message.exMap['matchScore'] = message.sendTime?.toDouble() ?? 0.0;
        filteredMessages.add(message);
      }
    }

    // 统一按时间降序
    filteredMessages.sort((a, b) {
      final ta = a.sendTime ?? 0;
      final tb = b.sendTime ?? 0;
      return tb.compareTo(ta);
    });

    return filteredMessages;
  }
  // ... existing code ...

  // 计算匹配度分数（改为严格匹配：命中=1，未命中=0）
  double _calculateMatchScore(String content, String keyword) {
    if (content.isEmpty || keyword.isEmpty) return 0.0;
    return content.contains(keyword) ? 1.0 : 0.0;
  }
  
  // 检查是否为完整单词匹配
  bool _isWholeWordMatch(String content, String keyword) {
    final regex = RegExp(r'\b' + RegExp.escape(keyword) + r'\b', caseSensitive: false);
    return regex.hasMatch(content);
  }

  // 根据搜索类型获取消息类型列表
  List<int> _getMessageTypesBySearchType() {
    switch (selectedSearchType.value) {
      case 1: // 文本
        return [MessageType.text, MessageType.atText, MessageType.quote];
      case 2: // 图片
        return [MessageType.picture, MessageType.video];
      case 3: // 文件
        return [MessageType.file];
      default: // 全部
        return [];
    }
  }

  // 切换搜索类型
  void changeSearchType(int type) {
    selectedSearchType.value = type;
    
    // 如果切换到图片或文件类型，自动加载所有相关媒体文件
    if (type == 2 || type == 3) {
      _loadAllMediaFiles(type);
    } else if (searchKeyword.value.isNotEmpty) {
      performSearch();
    } else {
      // 切换到全部或文本类型且没有搜索关键词时，清空结果
      searchResults.clear();
      hasSearched.value = false;
    }
  }

  // 加载所有媒体文件（图片或文件）
  Future<void> _loadAllMediaFiles(int type) async {
    isSearching.value = true;
    hasSearched.value = true;
    currentPage = 1;
    hasMoreData = true;
    searchResults.clear();

    try {
      // 根据类型获取对应的消息类型列表
      List<int> messageTypes;
      switch (type) {
        case 2: // 图片
          messageTypes = [MessageType.picture, MessageType.video];
          break;
        case 3: // 文件
          messageTypes = [MessageType.file];
          break;
        default:
          messageTypes = [];
      }
      
      final result = await OpenIM.iMManager.messageManager.searchLocalMessages(
        conversationID: conversationID,
        keywordList: [], // 空关键词列表，获取所有消息
        messageTypeList: messageTypes,
        pageIndex: currentPage,
        count: pageSize,
      );

      if (result.searchResultItems?.isNotEmpty == true) {
        final allMessages = <Message>[];
        for (final item in result.searchResultItems!) {
          if (item.messageList?.isNotEmpty == true) {
            allMessages.addAll(item.messageList!);
          }
        }
        
        // 按时间倒序排列
        allMessages.sort((a, b) => (b.sendTime ?? 0).compareTo(a.sendTime ?? 0));
        searchResults.addAll(allMessages);
        
        // 检查是否还有更多数据
        hasMoreData = allMessages.length >= pageSize;
        currentPage++;
      } else {
        hasMoreData = false;
      }
    } catch (e) {
      IMViews.showToast('加载失败：$e');
      hasMoreData = false;
    } finally {
      isSearching.value = false;
    }
  }

  // 跳转到消息位置
  void jumpToMessage(Message message) {
    Get.back(result: {
      'action': 'jumpToMessage',
      'message': message,
    });
  }
  // 跳转到个人资料页面
  void openUserProfile(Message message) {
    AppNavigator.startUserProfilePane(
      userID: message.sendID!,
      nickname: message.senderNickname,
      faceURL: message.senderFaceUrl,
    );
  }
  // 清空搜索
  void clearSearch() {
    searchController.clear();
    searchResults.clear();
    hasSearched.value = false;
    searchKeyword.value = '';
    selectedSearchType.value = 0;
    hasSearchText.value = false; // 重置响应式变量
  }

  // 格式化消息内容用于显示
  String getMessageDisplayContent(Message message) {
    switch (message.contentType) {
      case MessageType.text:
        return message.textElem?.content ?? '';
      case MessageType.atText:
        return message.atTextElem?.text ?? '';
      case MessageType.quote:
        // 处理引用消息：返回引用消息的文本内容
        final quoteText = message.quoteElem?.text ?? '';
        final quotedContent = message.quoteElem?.quoteMessage?.textElem?.content ?? 
                             message.quoteElem?.quoteMessage?.atTextElem?.text ?? '';
        // 组合当前回复内容和被引用的内容，以便都能被搜索到
        return '$quoteText $quotedContent'.trim();
      case MessageType.picture:
        return '[图片]';
      case MessageType.video:
        return '[视频]';
      case MessageType.file:
        return '[文件] ${message.fileElem?.fileName ?? ''}';
      case MessageType.voice:
        return '[语音]';
      case MessageType.location:
        return '[位置]';
      default:
        return '[消息]';
    }
  }

  // 高亮搜索关键词（增强版，支持模糊匹配高亮）
  List<TextSpan> getHighlightedText(String text, String keyword) {
    if (keyword.isEmpty) {
      return [TextSpan(text: text)];
    }

    final List<TextSpan> spans = [];
    final String lowerText = text.toLowerCase();
    final String lowerKeyword = keyword.toLowerCase();
    
    // 首先尝试完全匹配
    final exactMatches = <int>[];
    int start = 0;
    int index = lowerText.indexOf(lowerKeyword, start);
    
    while (index != -1) {
      exactMatches.add(index);
      start = index + 1;
      index = lowerText.indexOf(lowerKeyword, start);
    }
    
    if (exactMatches.isNotEmpty) {
      // 有完全匹配，使用完全匹配高亮
      start = 0;
      for (final matchIndex in exactMatches) {
        // 添加匹配前的文本
        if (matchIndex > start) {
          spans.add(TextSpan(
            text: text.substring(start, matchIndex),
            style: Styles.ts_0C1C33_14sp,
          ));
        }
        
        // 添加高亮的匹配文本
        spans.add(TextSpan(
          text: text.substring(matchIndex, matchIndex + keyword.length),
          style: Styles.ts_0089FF_16sp.copyWith(
            backgroundColor: Styles.c_0089FF.withOpacity(0.2),
          ),
        ));
        
        start = matchIndex + keyword.length;
      }
      
      // 添加剩余文本
      if (start < text.length) {
        spans.add(TextSpan(
          text: text.substring(start),
          style: Styles.ts_0C1C33_14sp,
        ));
      }
    } else {
      // 没有完全匹配，尝试字符级别的模糊高亮
      final highlightedChars = <bool>[];
      for (int i = 0; i < text.length; i++) {
        highlightedChars.add(false);
      }
      
      // 标记匹配的字符
      for (int i = 0; i < text.length; i++) {
        for (int j = 0; j < keyword.length; j++) {
          if (lowerText[i] == lowerKeyword[j]) {
            highlightedChars[i] = true;
            break;
          }
        }
      }
      
      // 构建TextSpan
      start = 0;
      for (int i = 0; i < highlightedChars.length; i++) {
        if (highlightedChars[i] != (i > 0 ? highlightedChars[i - 1] : false)) {
          if (i > start) {
            spans.add(TextSpan(
              text: text.substring(start, i),
              style: highlightedChars[start] 
                  ? Styles.ts_0089FF_16sp.copyWith(backgroundColor: Styles.c_0089FF.withOpacity(0.1))
                  : Styles.ts_0C1C33_14sp,
            ));
          }
          start = i;
        }
      }
      
      // 添加最后一段
      if (start < text.length) {
        spans.add(TextSpan(
          text: text.substring(start),
          style: highlightedChars[start] 
              ? Styles.ts_0089FF_16sp.copyWith(backgroundColor: Styles.c_0089FF.withOpacity(0.1))
              : Styles.ts_0C1C33_14sp,
        ));
      }
    }
    
    return spans;
  }
  // 格式化时间显示
  String formatMessageTime(int timestamp) {
    final DateTime messageTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
    final DateTime now = DateTime.now();
    final DateTime today = DateTime(now.year, now.month, now.day);
    final DateTime messageDate = DateTime(messageTime.year, messageTime.month, messageTime.day);
    
    if (messageDate == today) {
      return IMUtils.getChatTimeline(timestamp, 'HH:mm');
    } else if (messageDate == today.subtract(Duration(days: 1))) {
      return '昨天 ${IMUtils.getChatTimeline(timestamp, 'HH:mm')}';
    } else if (messageTime.year == now.year) {
      return '${messageTime.month}月${messageTime.day}日 ${IMUtils.getChatTimeline(timestamp, 'HH:mm')}';
    } else {
      return '${messageTime.year}年${messageTime.month}月${messageTime.day}日 ${IMUtils.getChatTimeline(timestamp, 'HH:mm')}';
    }
  }
}